import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

warnings.filterwarnings('ignore')

# 设置绘图风格
sns.set(style="whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 1. 加载训练数据
train_data = pd.read_csv('train.csv')  

# 2. 检查标签分布
label_counts = train_data['label'].value_counts()
label_percent = train_data['label'].value_counts(normalize=True) * 100

# 3. 打印标签分布统计
print("=" * 50)
print("标签分布统计:")
print(f"重复购买(label=1)的样本数: {label_counts[1]} ({label_percent[1]:.2f}%)")
print(f"非重复购买(label=0)的样本数: {label_counts[0]} ({label_percent[0]:.2f}%)")
print(f"总样本数: {len(train_data)}")
print(f"类别比例(0:1): {label_counts[0] / label_counts[1]:.2f}:1")

# 4. 判断是否严重不平衡
imbalance_threshold = 0.2  # 设定严重不平衡的阈值（少数类占比<20%）
minority_percent = min(label_percent)

if minority_percent < imbalance_threshold * 100:
    print("\n警告: 存在严重的类别不平衡问题!")
    print(f"少数类占比仅{minority_percent:.2f}%，低于{imbalance_threshold * 100:.0f}%的阈值")
else:
    print("\n类别分布相对平衡")

# 5. 可视化标签分布
plt.figure(figsize=(12, 6))

# 饼图
plt.subplot(1, 2, 1)
colors = ['#ff9999', '#66b3ff']
explode = (0.05, 0) if minority_percent < 20 else (0, 0)
labels = [f'非重复购买\n({label_percent[0]:.2f}%)',
          f'重复购买\n({label_percent[1]:.2f}%)']
plt.pie(label_counts, colors=colors, autopct='%1.1f%%',
        startangle=90, pctdistance=0.85, explode=explode,
        textprops={'fontsize': 12})
# 绘制中心圆
centre_circle = plt.Circle((0, 0), 0.70, fc='white')
fig = plt.gcf()
fig.gca().add_artist(centre_circle)
plt.title('标签分布 - 饼图', fontsize=14)
plt.axis('equal')

# 条形图
plt.subplot(1, 2, 2)
ax = sns.countplot(data=train_data, x='label', palette=colors)
plt.title('标签分布 - 条形图', fontsize=14)
plt.xlabel('是否重复购买', fontsize=12)
plt.ylabel('样本数量', fontsize=12)
plt.xticks([0, 1], ['非重复购买 (0)', '重复购买 (1)'])

# 在条形上添加数值标签
for p in ax.patches:
    height = p.get_height()
    ax.text(p.get_x() + p.get_width() / 2., height + 0.01 * max(label_counts),
            f'{height}\n({height / len(train_data) * 100:.1f}%)',
            ha='center', va='bottom', fontsize=10)

plt.tight_layout()
plt.show()
